﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Quickly.Identity.EntityFrameworkCore;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.Extensions.DependencyInjection;

public static class QuickIdentityEntityFrameworkCoreExtensions
{
    public static void ValidateDatabaseConnectionString(string? database, string? connectionString)
    {
        ArgumentNullException.ThrowIfNullOrWhiteSpace(database, nameof(database));
        ArgumentNullException.ThrowIfNullOrWhiteSpace(connectionString, nameof(connectionString));
    }

    public static DbContextOptionsBuilder ConfigureDbContextOptions(string database, string connectionString, DbContextOptionsBuilder options) => database switch
    {
        Constants.SuppoertDatabaseTypes.Sqlite => options.UseSqlite(connectionString),
        Constants.SuppoertDatabaseTypes.Postgres => options.UseNpgsql(connectionString),
        _ => throw new NotSupportedException($"支持的数据库：{Constants.SuppoertDatabaseTypes.Sqlite},{Constants.SuppoertDatabaseTypes.Postgres}"),
    };

    public static Action<DbProvider, IConfiguration, DbContextOptionsBuilder> ConfigureDatabase = (provider, configuration, options) =>
    {
        var connectionString = configuration.GetConnectionString(provider.ConnectionName);

        if (string.IsNullOrWhiteSpace(connectionString))
        {
            throw new ArgumentNullException($"ConnectionStrings:{provider.ConnectionName}");
        }

        ConfigureDbContextOptions(provider.Name, connectionString, options);
    };

    public static IServiceCollection AddIdentityDbContextQuickly<TDbContext>(this IServiceCollection services, IConfiguration configuration, Action<DbContextOptionsBuilder>? configure = null)
        where TDbContext : DbContext
    {
        var dbProvider = new DbProvider(string.Empty, string.Empty);
        configuration.GetSection("DbProvider").Bind(dbProvider);

        services.AddDbContext<QuickIdentityDbContext>(options =>
        {
            ConfigureDatabase(dbProvider, configuration, options);
            configure?.Invoke(options);
        });

        services.AddTransient<DbContext>(s => s.GetRequiredService<TDbContext>());

        return services;
    }


    public static IServiceCollection AddDbProviderOption(this IServiceCollection services, IConfigurationRoot configurationRoot)
    {
        services.Configure<DbProvider>(configurationRoot.GetSection("DbProvider"));

        return services;
    }
}
